<template>
  <div class="api-listener-page">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="page-title">
        <div class="title-with-back">
          <el-button 
            type="primary" 
            :icon="ArrowLeft" 
            @click="$router.push('/tools')"
            class="blue-return-button"
            circle
          />
          <div class="title-content">
            <div class="title-main">
              <el-icon class="title-icon"><Link /></el-icon>
              <h2>爬虫队列接口</h2>
            </div>
            <p class="page-description">
              <el-icon><Document /></el-icon>
              <span>通用爬虫队列接口，支持自定义JSON模板和Kafka监听</span>
            </p>
          </div>
        </div>
      </div>
      <div class="page-actions">
        <el-tag v-if="isExecuting" type="success" :icon="Loading">执行中</el-tag>
        <el-tag v-else type="info" :icon="CircleCheck">就绪</el-tag>
      </div>
    </div>

    <!-- 主要内容区域 -->
    <div class="main-content">
      <!-- 配置表单 -->
      <div class="config-form">
        <el-card>
          <template #header>
            <div class="card-header">
              <div class="card-header-title">
                <el-icon class="card-icon"><Setting /></el-icon>
                <span>爬虫队列接口配置</span>
              </div>
              <el-button 
                v-if="!isExecuting" 
                type="primary" 
                @click="executeApiListener" 
                :disabled="!isFormValid"
              >
                执行接口
              </el-button>
              <el-button 
                v-else 
                type="danger" 
                @click="cancelExecution"
              >
                取消执行
              </el-button>
            </div>
          </template>

          <el-form :model="formData" label-width="140px" class="config-form-content">
            <!-- 1. 选择接口配置 -->
            <el-form-item label="接口配置">
              <el-select 
                v-model="formData.configId" 
                placeholder="请选择爬虫队列接口配置" 
                @change="onConfigChange"
                style="width: 100%"
              >
                <el-option
                  v-for="config in apiConfigs"
                  :key="config.id"
                  :label="config.config_name"
                  :value="config.id"
                >
                  <span style="float: left">{{ config.config_name }}</span>
                  <span style="float: right; color: #8492a6; font-size: 13px">
                    {{ config.description }}
                  </span>
                </el-option>
              </el-select>
            </el-form-item>

            <!-- 2. 选择Kafka环境 -->
            <el-form-item label="Kafka环境">
              <el-select 
                v-model="formData.kafkaEnvId" 
                placeholder="请选择Kafka环境配置" 
                style="width: 100%"
                :loading="environmentsLoading"
              >
                <el-option
                  v-for="env in kafkaEnvironments"
                  :key="env.id"
                  :label="env.config_name"
                  :value="env.id"
                >
                  <span style="float: left">{{ env.config_name }}</span>
                  <span style="float: right; color: #8492a6; font-size: 13px">
                    {{ env.host }}:{{ env.port }}
                  </span>
                </el-option>
              </el-select>
            </el-form-item>

            <!-- 3. 监听主题 -->
            <el-form-item label="监听主题">
              <el-input
                v-model="formData.listenTopic"
                placeholder="请输入要监听的Kafka主题名称"
                clearable
              >
                <template #append>
                  <el-button :icon="QuestionFilled" @click="showTopicHelp" />
                </template>
              </el-input>
            </el-form-item>

            <!-- 4. 匹配配置 -->
            <el-form-item label="匹配配置">
              <div class="match-config-container">
                <!-- 匹配类型选择 -->
                <el-radio-group v-model="formData.matchType" class="match-type-selector">
                  <el-radio value="key_value">键值对匹配</el-radio>
                  <el-radio value="fuzzy">模糊匹配</el-radio>
                </el-radio-group>

                <!-- 键值对匹配 -->
                <div v-if="formData.matchType === 'key_value'" class="key-value-inputs">
                  <div class="input-row">
                    <div class="input-group">
                      <label class="input-label">键名 (Key)</label>
                      <el-input
                        v-model="formData.matchKey"
                        placeholder="例如: video_id"
                        clearable
                        class="key-input"
                      />
                    </div>
                    <div class="equals-sign">=</div>
                    <div class="input-group">
                      <label class="input-label">键值 (Value)</label>
                      <el-input
                        v-model="formData.matchValue"
                        placeholder="例如: 7548698496694504746"
                        clearable
                        class="value-input"
                      />
                    </div>
                  </div>
                  <div class="match-preview" v-if="formData.matchKey && formData.matchValue">
                    <el-tag size="small" type="success">
                      将匹配: "{{ formData.matchKey }}": "{{ formData.matchValue }}"
                    </el-tag>
                  </div>
                </div>

                <!-- 模糊匹配 -->
                <div v-else class="fuzzy-input">
                  <el-input
                    v-model="formData.matchValue"
                    placeholder="输入任意关键字进行模糊匹配"
                    clearable
                  />
                  <div class="match-preview" v-if="formData.matchValue">
                    <el-tag size="small" type="warning">
                      将在JSON中查找包含: {{ formData.matchValue }}
                    </el-tag>
                  </div>
                </div>

                <!-- 帮助按钮 -->
                <div class="help-button-container">
                  <el-button 
                    :icon="QuestionFilled" 
                    @click="showMatchValueHelp"
                    size="small"
                    text
                  >
                    匹配说明
                  </el-button>
                </div>
              </div>
            </el-form-item>

            <!-- 5. 超时时间 -->
            <el-form-item label="数据等待超时">
              <el-input-number
                v-model="formData.timeout"
                :min="30"
                :max="1800"
                :step="30"
                style="width: 200px"
              />
              <span style="margin-left: 10px; color: #606266">秒</span>
              <el-tooltip content="等待Kafka数据返回的最大时间，超时后任务结束" placement="right">
                <el-icon style="margin-left: 8px; color: #909399; cursor: help">
                  <QuestionFilled />
                </el-icon>
              </el-tooltip>
            </el-form-item>

            <!-- 6. JSON模板编辑 -->
            <el-form-item label="JSON模板">
              <div class="json-template-container">
                <div class="json-template-header">
                  <span>请修改JSON模板以适配不同业务需求</span>
                  <div class="template-actions">
                    <el-button size="small" @click="resetJsonTemplate">重置</el-button>
                    <el-button size="small" @click="formatJsonTemplate">格式化</el-button>
                    <el-button size="small" @click="validateJsonTemplate">验证</el-button>
                  </div>
                </div>
                
                <!-- JSON验证状态提示 -->
                <div v-if="jsonTemplateStr.trim()" class="json-validation-status">
                  <el-alert
                    v-if="jsonValidationStatus.show"
                    :title="jsonValidationStatus.valid ? 'JSON格式正确' : 'JSON格式错误'"
                    :type="jsonValidationStatus.valid ? 'success' : 'error'"
                    :description="jsonValidationStatus.message"
                    show-icon
                    :closable="false"
                    size="small"
                  />
                </div>
                
                <el-input
                  v-model="jsonTemplateStr"
                  type="textarea"
                  :rows="12"
                  placeholder="JSON模板将在选择接口配置后自动加载"
                  class="json-template-editor"
                  @input="onJsonTemplateChange"
                />
              </div>
            </el-form-item>
          </el-form>
        </el-card>
      </div>

      <!-- 执行结果 -->
      <div v-if="executionResult || isExecuting" class="result-section">
        <el-card>
          <template #header>
            <div class="card-header">
              <div class="card-header-title">
                <el-icon class="card-icon"><TrendCharts /></el-icon>
                <span>执行结果</span>
              </div>
              <div class="result-actions" v-if="executionResult && !isExecuting">
                <el-button @click="expandAllSections" size="small" :icon="ArrowDown">全部展开</el-button>
                <el-button @click="collapseAllSections" size="small" :icon="ArrowUp">全部折叠</el-button>
                <el-button size="small" @click="clearResult">清空结果</el-button>
              </div>
            </div>
          </template>

          <!-- 执行中状态 -->
          <div v-if="isExecuting" class="execution-status">
            <el-steps :active="currentExecutionStep" align-center>
              <el-step title="启动Kafka监听" />
              <el-step title="触发API接口" />
              <el-step title="等待数据匹配" />
              <el-step title="执行完成" />
            </el-steps>
            <div class="execution-progress">
              <el-progress :percentage="executionProgress" :status="executionStatus" />
              <p class="execution-message">{{ executionMessage }}</p>
            </div>
          </div>

          <!-- 执行结果展示 -->
          <div v-if="executionResult && !isExecuting" class="execution-result">
            <el-alert
              :title="executionResult.success ? '执行成功' : '执行失败'"
              :type="executionResult.success ? 'success' : 'error'"
              :description="executionResult.message"
              show-icon
              :closable="false"
            />

            <div v-if="executionResult.success && executionResult.data" class="result-data">
              <!-- API响应 -->
              <div class="result-section">
                <div class="section-header">
                  <h4>API响应结果</h4>
                  <div class="section-actions">
                    <el-button 
                      @click="toggleSection('apiResponse')" 
                      :icon="sectionExpanded.apiResponse ? ArrowUp : ArrowDown"
                      size="small"
                      text
                      type="primary"
                    >
                      {{ sectionExpanded.apiResponse ? '折叠' : '展开' }}
                    </el-button>
                    <el-button 
                      @click="copyJsonData(executionResult.data.api_response, 'API响应')" 
                      :icon="DocumentCopy"
                      size="small"
                      text
                      type="info"
                      title="复制JSON"
                    />
                  </div>
                </div>
                <div class="json-content-wrapper" v-show="sectionExpanded.apiResponse">
                  <pre class="json-content">{{ formatJson(executionResult.data.api_response) }}</pre>
                </div>
                <div class="json-preview" v-show="!sectionExpanded.apiResponse" @click="toggleSection('apiResponse')">
                  <span class="preview-text">{{ getJsonPreview(executionResult.data.api_response) }}</span>
                </div>
              </div>

              <!-- Kafka数据 -->
              <div class="result-section">
                <div class="section-header">
                  <h4>Kafka匹配数据</h4>
                  <div class="section-actions">
                    <el-button 
                      @click="toggleSection('kafkaData')" 
                      :icon="sectionExpanded.kafkaData ? ArrowUp : ArrowDown"
                      size="small"
                      text
                      type="primary"
                    >
                      {{ sectionExpanded.kafkaData ? '折叠' : '展开' }}
                    </el-button>
                    <el-button 
                      @click="copyJsonData(executionResult.data.kafka_data, 'Kafka数据')" 
                      :icon="DocumentCopy"
                      size="small"
                      text
                      type="info"
                      title="复制JSON"
                    />
                  </div>
                </div>
                <div class="json-content-wrapper" v-show="sectionExpanded.kafkaData">
                  <pre class="json-content">{{ formatJson(executionResult.data.kafka_data) }}</pre>
                </div>
                <div class="json-preview" v-show="!sectionExpanded.kafkaData" @click="toggleSection('kafkaData')">
                  <span class="preview-text">{{ getJsonPreview(executionResult.data.kafka_data) }}</span>
                </div>
              </div>

              <!-- 执行摘要 -->
              <div class="result-section">
                <h4>执行摘要</h4>
                <el-descriptions :column="2" border>
                  <el-descriptions-item label="监听主题">
                    {{ executionResult.data.execution_summary?.listen_topic }}
                  </el-descriptions-item>
                  <el-descriptions-item label="匹配值">
                    {{ executionResult.data.execution_summary?.match_value }}
                  </el-descriptions-item>
                  <el-descriptions-item label="API地址">
                    {{ executionResult.data.execution_summary?.api_url }}
                  </el-descriptions-item>
                  <el-descriptions-item label="执行时间">
                    {{ executionResult.data.execution_summary?.execution_time }}
                  </el-descriptions-item>
                </el-descriptions>
              </div>
            </div>
          </div>
        </el-card>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  Loading, CircleCheck, QuestionFilled, ArrowLeft, Link, Document, Setting, TrendCharts,
  ArrowUp, ArrowDown, DocumentCopy
} from '@element-plus/icons-vue'
import { componentLogger } from '@/utils/logger'
import { copyJsonToClipboard } from '@/utils/clipboard'
import api from '@/utils/api'

// 页面状态
const isExecuting = ref(false)
const currentExecutionStep = ref(0)
const executionProgress = ref(0)
const executionStatus = ref('')
const executionMessage = ref('')
const executionResult = ref(null)

// 数据展示折叠状态
const sectionExpanded = reactive({
  apiResponse: true,  // 默认展开
  kafkaData: true     // 默认展开
})

// 表单数据
const formData = reactive({
  configId: '',
  kafkaEnvId: '',
  listenTopic: '',
  matchType: 'key_value', // 默认使用键值对匹配
  matchKey: '',
  matchValue: '',
  timeout: 300
})

// 配置数据
const apiConfigs = ref([])
const kafkaEnvironments = ref([])
const jsonTemplateStr = ref('')
const originalTemplate = ref({})

// JSON验证状态
const jsonValidationStatus = reactive({
  show: false,
  valid: false,
  message: ''
})

// 计算属性
const isFormValid = computed(() => {
  // 基础字段验证
  let basicFieldsValid = formData.configId && 
                        formData.kafkaEnvId && 
                        formData.listenTopic && 
                        jsonTemplateStr.value.trim()
  
  // 匹配配置验证
  if (formData.matchType === 'key_value') {
    // 键值对匹配需要键名和键值都不为空
    basicFieldsValid = basicFieldsValid && formData.matchKey.trim() && formData.matchValue.trim()
  } else {
    // 模糊匹配只需要匹配值不为空
    basicFieldsValid = basicFieldsValid && formData.matchValue.trim()
  }
  
  if (!basicFieldsValid) {
    return false
  }
  
  // JSON模板验证
  const jsonValidation = validateJsonTemplateStrict()
  return jsonValidation.valid
})

// 页面初始化
onMounted(async () => {
  componentLogger.info('爬虫队列接口页面初始化')
  await loadApiConfigs()
  await loadKafkaEnvironments()
})

// 页面卸载时清理
onBeforeUnmount(() => {
  // 如果正在执行，取消执行
  if (isExecuting.value) {
    cancelExecution()
  }
  
  // 清理定时器
  if (jsonValidationTimer) {
    clearTimeout(jsonValidationTimer)
  }
})

// 加载API配置
async function loadApiConfigs() {
  try {
    const response = await api.get('/api-listener/configs', {
      timeout: 10000 // 10秒超时
    })
    if (response.data.success) {
      apiConfigs.value = response.data.data || []
      if (apiConfigs.value.length === 0) {
        ElMessage.warning('未找到可用的API配置')
      } else {
        componentLogger.info(`加载到 ${apiConfigs.value.length} 个API配置`)
      }
    } else {
      ElMessage.error('加载API配置失败: ' + response.data.message)
      apiConfigs.value = []
    }
  } catch (error) {
    componentLogger.error('加载API配置异常', error)
    apiConfigs.value = [] // 确保清空
    ElMessage.error({
      message: '加载API配置失败: ' + (error.message || '网络错误'),
      duration: 5000
    })
  }
}

// Kafka环境加载状态
const environmentsLoading = ref(false)

// 加载Kafka环境
async function loadKafkaEnvironments() {
  // 防止重复加载
  if (environmentsLoading.value) {
    componentLogger.warn('环境加载中,请稍候')
    return
  }
  
  environmentsLoading.value = true
  try {
    const response = await api.get('/api-listener/kafka-environments', {
      timeout: 10000 // 10秒超时
    })
    if (response.data.success) {
      kafkaEnvironments.value = response.data.data || []
      if (kafkaEnvironments.value.length === 0) {
        ElMessage.warning('未找到可用的Kafka环境配置')
      } else {
        componentLogger.info(`加载到 ${kafkaEnvironments.value.length} 个Kafka环境`)
      }
    } else {
      ElMessage.error('加载Kafka环境失败: ' + response.data.message)
      kafkaEnvironments.value = []
    }
  } catch (error) {
    componentLogger.error('加载Kafka环境异常', error)
    kafkaEnvironments.value = [] // 确保清空
    ElMessage.error({
      message: '加载Kafka环境失败: ' + (error.message || '网络错误'),
      duration: 5000
    })
  } finally {
    environmentsLoading.value = false
  }
}

// 配置变更处理
function onConfigChange(configId) {
  const selectedConfig = apiConfigs.value.find(config => config.id === configId)
  if (selectedConfig && selectedConfig.request_template) {
    originalTemplate.value = selectedConfig.request_template
    jsonTemplateStr.value = JSON.stringify(selectedConfig.request_template, null, 2)
    ElMessage.success('已加载JSON模板，请根据需要修改')
    
    // 验证加载的模板
    updateJsonValidationStatus()
  }
}

// JSON模板变更处理
function onJsonTemplateChange() {
  // 防抖处理，避免频繁验证
  clearTimeout(jsonValidationTimer)
  jsonValidationTimer = setTimeout(() => {
    updateJsonValidationStatus()
  }, 500)
}

// 更新JSON验证状态
function updateJsonValidationStatus() {
  if (!jsonTemplateStr.value.trim()) {
    jsonValidationStatus.show = false
    return
  }
  
  const result = validateJsonTemplateStrict()
  jsonValidationStatus.show = true
  jsonValidationStatus.valid = result.valid
  jsonValidationStatus.message = result.valid ? result.message : result.error
}

// 验证定时器
let jsonValidationTimer = null

// JSON模板操作
function resetJsonTemplate() {
  if (Object.keys(originalTemplate.value).length > 0) {
    jsonTemplateStr.value = JSON.stringify(originalTemplate.value, null, 2)
    updateJsonValidationStatus()
    ElMessage.success('JSON模板已重置')
  } else {
    ElMessage.warning('请先选择接口配置')
  }
}

function formatJsonTemplate() {
  try {
    const parsed = JSON.parse(jsonTemplateStr.value)
    jsonTemplateStr.value = JSON.stringify(parsed, null, 2)
    updateJsonValidationStatus()
    ElMessage.success('JSON格式化成功')
  } catch (error) {
    ElMessage.error('JSON格式错误: ' + error.message)
  }
}

function validateJsonTemplate() {
  const result = validateJsonTemplateStrict()
  if (result.valid) {
    ElMessage.success('JSON格式验证通过')
  } else {
    ElMessage.error('JSON格式错误: ' + result.error)
  }
}

// 严格的JSON模板验证函数
function validateJsonTemplateStrict() {
  try {
    // 1. 基础JSON格式验证
    if (!jsonTemplateStr.value || !jsonTemplateStr.value.trim()) {
      return {
        valid: false,
        error: 'JSON模板不能为空'
      }
    }

    // 2. JSON语法验证
    let parsedJson
    try {
      parsedJson = JSON.parse(jsonTemplateStr.value.trim())
    } catch (syntaxError) {
      return {
        valid: false,
        error: `JSON语法错误: ${syntaxError.message}`
      }
    }

    // 3. 数据类型验证
    if (typeof parsedJson !== 'object' || parsedJson === null || Array.isArray(parsedJson)) {
      return {
        valid: false,
        error: 'JSON模板必须是一个对象（{}），不能是数组或基础类型'
      }
    }

    // 4. 必要字段验证（根据爬虫队列接口的要求）
    const requiredFields = ['seed_data', 'queue_name']
    const missingFields = []
    
    for (const field of requiredFields) {
      if (!(field in parsedJson)) {
        missingFields.push(field)
      }
    }
    
    if (missingFields.length > 0) {
      return {
        valid: false,
        error: `缺少必要字段: ${missingFields.join(', ')}`
      }
    }

    // 5. seed_data字段类型验证
    if (!Array.isArray(parsedJson.seed_data)) {
      return {
        valid: false,
        error: 'seed_data字段必须是数组类型'
      }
    }

    if (parsedJson.seed_data.length === 0) {
      return {
        valid: false,
        error: 'seed_data数组不能为空'
      }
    }

    // 6. seed_data数组元素验证
    for (let i = 0; i < parsedJson.seed_data.length; i++) {
      const seedItem = parsedJson.seed_data[i]
      if (typeof seedItem !== 'object' || seedItem === null || Array.isArray(seedItem)) {
        return {
          valid: false,
          error: `seed_data[${i}] 必须是对象类型`
        }
      }
    }

    // 7. queue_name字段验证
    if (typeof parsedJson.queue_name !== 'string' || parsedJson.queue_name.trim() === '') {
      return {
        valid: false,
        error: 'queue_name字段必须是非空字符串'
      }
    }

    // 8. 检查是否包含不安全的内容
    const jsonStr = JSON.stringify(parsedJson)
    const unsafePatterns = [
      /<script/i,
      /javascript:/i,
      /on\w+\s*=/i,
      /eval\s*\(/i,
      /function\s*\(/i
    ]

    for (const pattern of unsafePatterns) {
      if (pattern.test(jsonStr)) {
        return {
          valid: false,
          error: '检测到不安全的内容，请检查JSON模板'
        }
      }
    }

    // 9. 大小限制验证
    if (jsonStr.length > 10240) { // 10KB限制
      return {
        valid: false,
        error: 'JSON模板过大，请控制在10KB以内'
      }
    }

    // 10. 嵌套深度验证
    const maxDepth = getJsonDepth(parsedJson)
    if (maxDepth > 10) {
      return {
        valid: false,
        error: 'JSON嵌套层级过深，请控制在10层以内'
      }
    }

    return {
      valid: true,
      data: parsedJson,
      message: 'JSON模板验证通过'
    }

  } catch (error) {
    return {
      valid: false,
      error: `验证过程中发生错误: ${error.message}`
    }
  }
}

// 计算JSON对象的嵌套深度
function getJsonDepth(obj, currentDepth = 1) {
  if (typeof obj !== 'object' || obj === null) {
    return currentDepth
  }

  let maxDepth = currentDepth
  
  if (Array.isArray(obj)) {
    for (const item of obj) {
      const depth = getJsonDepth(item, currentDepth + 1)
      maxDepth = Math.max(maxDepth, depth)
    }
  } else {
    for (const value of Object.values(obj)) {
      const depth = getJsonDepth(value, currentDepth + 1)
      maxDepth = Math.max(maxDepth, depth)
    }
  }
  
  return maxDepth
}

// 执行爬虫队列接口
async function executeApiListener() {
  try {
    // 严格验证JSON模板
    const jsonValidationResult = validateJsonTemplateStrict()
    if (!jsonValidationResult.valid) {
      ElMessage.error('JSON模板验证失败: ' + jsonValidationResult.error)
      return
    }

    const jsonTemplate = jsonValidationResult.data

    isExecuting.value = true
    currentExecutionStep.value = 0
    executionProgress.value = 0
    executionStatus.value = 'active'
    executionMessage.value = '正在启动执行流程...'
    executionResult.value = null

    componentLogger.info('开始执行爬虫队列接口', formData)

    // 构建请求数据
    const requestData = {
      config_id: formData.configId,
      kafka_env_id: formData.kafkaEnvId,
      listen_topic: formData.listenTopic,
      json_template: jsonTemplate,
      match_type: formData.matchType,
      match_key: formData.matchKey,
      match_value: formData.matchValue,
      timeout_seconds: formData.timeout
    }

    // 模拟执行步骤
    updateExecutionStatus(1, 25, '正在启动Kafka监听...')
    await sleep(1000)

    updateExecutionStatus(2, 50, '正在触发API接口...')
    await sleep(1000)

    updateExecutionStatus(3, 75, '正在等待Kafka数据匹配...')

    // 调用后端API (HTTP超时自动适配Kafka等待时间，用户无需关心)
    // HTTP超时 = Math.max(Kafka等待时间 + 30秒缓冲, 60秒最小值)
    const httpTimeoutMs = Math.max((formData.timeout + 30) * 1000, 60000)
    const response = await api.post('/api-listener/execute', requestData, {
      timeout: httpTimeoutMs
    })
    
    updateExecutionStatus(4, 100, '执行完成')
    
    executionResult.value = response.data
    
    if (response.data.success) {
      ElMessage.success('爬虫队列接口执行成功')
      executionStatus.value = 'success'
    } else {
      ElMessage.error('执行失败: ' + response.data.message)
      executionStatus.value = 'exception'
    }

  } catch (error) {
    componentLogger.error('执行爬虫队列接口异常', error)
    executionResult.value = {
      success: false,
      message: error.message || '执行异常',
      timestamp: new Date().toISOString()
    }
    executionStatus.value = 'exception'
    ElMessage.error('执行异常: ' + error.message)
  } finally {
    isExecuting.value = false
  }
}

// 更新执行状态
function updateExecutionStatus(step, progress, message) {
  currentExecutionStep.value = step
  executionProgress.value = progress
  executionMessage.value = message
}

// 取消执行
function cancelExecution() {
  isExecuting.value = false
  currentExecutionStep.value = 0
  executionProgress.value = 0
  executionMessage.value = ''
  ElMessage.success('已取消执行')
}

// 清空结果
function clearResult() {
  executionResult.value = null
  currentExecutionStep.value = 0
  executionProgress.value = 0
  executionMessage.value = ''
}

// 帮助信息
function showTopicHelp() {
  ElMessageBox.alert(
    '请输入要监听的Kafka主题名称，例如：\n' +
    '• ods_dy_video_details_one（视频详情）\n' +
    '• ods_by_talent_search_detail（达人搜索）\n' +
    '• ods_by_captain_overview（团长搜索）',
    '监听主题帮助',
    { confirmButtonText: '确定' }
  )
}

function showMatchValueHelp() {
  ElMessageBox.alert(
    '匹配值支持两种格式：\n\n' +
    '🎯 键值对匹配（推荐）：\n' +
    '• 格式：key=value\n' +
    '• 示例：video_id=7548698496694504746\n' +
    '• 说明：精确匹配JSON中的键值对\n' +
    '• 支持：字符串和数字类型自动转换\n\n' +
    '🔍 模糊匹配：\n' +
    '• 格式：任意字符串\n' +
    '• 示例：7548698496694504746\n' +
    '• 说明：在整个JSON字符串中查找包含该值的数据\n\n' +
    '💡 建议使用键值对匹配，准确性更高！',
    '匹配值帮助',
    { 
      confirmButtonText: '确定',
      dangerouslyUseHTMLString: false
    }
  )
}

// 重置表单和结果
function resetFormAndResult() {
  formData.configId = apiConfigs.value.length > 0 ? apiConfigs.value[0].id : ''
  formData.kafkaEnvId = kafkaEnvironments.value.length > 0 ? kafkaEnvironments.value[0].id : ''
  formData.listenTopic = ''
  formData.matchType = 'key_value'
  formData.matchKey = ''
  formData.matchValue = ''
  formData.timeout = 300
  jsonTemplateStr.value = Object.keys(originalTemplate.value).length > 0 ? JSON.stringify(originalTemplate.value, null, 2) : ''
  isExecuting.value = false
  currentExecutionStep.value = 0
  executionProgress.value = 0
  executionStatus.value = ''
  executionMessage.value = '等待配置和执行'
  executionResult.value = null
  updateJsonValidationStatus()
  ElMessage.success('表单和结果已重置')
}

// 折叠/展开功能
function toggleSection(sectionName) {
  sectionExpanded[sectionName] = !sectionExpanded[sectionName]
}

function expandAllSections() {
  sectionExpanded.apiResponse = true
  sectionExpanded.kafkaData = true
  ElMessage.success('已展开所有数据')
}

function collapseAllSections() {
  sectionExpanded.apiResponse = false
  sectionExpanded.kafkaData = false
  ElMessage.success('已折叠所有数据')
}

// 复制JSON数据 - 使用统一工具
async function copyJsonData(data, label) {
  await copyJsonToClipboard(data, label)
}

// 格式化JSON显示
function formatJson(data) {
  try {
    if (typeof data === 'string') {
      return JSON.stringify(JSON.parse(data), null, 2)
    }
    return JSON.stringify(data, null, 2)
  } catch (error) {
    componentLogger.error('格式化JSON失败', error)
    return String(data)
  }
}

// 获取JSON预览
function getJsonPreview(data) {
  try {
    let jsonObj = data
    if (typeof data === 'string') {
      jsonObj = JSON.parse(data)
    }
    
    // 如果是对象，提取前3个键
    if (jsonObj && typeof jsonObj === 'object' && !Array.isArray(jsonObj)) {
      const keys = Object.keys(jsonObj)
      const preview = keys.slice(0, 3).map(key => {
        let value = jsonObj[key]
        if (typeof value === 'string' && value.length > 20) {
          value = value.substring(0, 20) + '...'
        } else if (typeof value === 'object') {
          value = '[Object]'
        }
        return `${key}: ${value}`
      }).join(', ')
      
      return `{ ${preview}${keys.length > 3 ? `, +${keys.length - 3} more` : ''} }`
    }
    
    // 如果是数组
    if (Array.isArray(jsonObj)) {
      return `[Array with ${jsonObj.length} items]`
    }
    
    // 其他类型
    const str = String(data)
    return str.length > 100 ? str.substring(0, 100) + '...' : str
  } catch (error) {
    const str = String(data)
    return str.length > 100 ? str.substring(0, 100) + '...' : str
  }
}

// 工具函数
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}
</script>

<style scoped>
.api-listener-page {
  padding: 0;
}

.match-config-container {
  width: 100%;
}

.match-type-selector {
  margin-bottom: 15px;
}

.key-value-inputs {
  margin-bottom: 10px;
}

.input-row {
  display: flex;
  align-items: flex-end;
  gap: 15px;
  margin-bottom: 10px;
}

.input-group {
  flex: 1;
}

.input-label {
  display: block;
  font-size: 12px;
  color: #606266;
  margin-bottom: 5px;
  font-weight: 500;
}

.equals-sign {
  font-size: 18px;
  font-weight: bold;
  color: #409EFF;
  padding-bottom: 6px;
  min-width: 20px;
  text-align: center;
}

.key-input {
  min-width: 150px;
}

.value-input {
  min-width: 200px;
}

.fuzzy-input {
  margin-bottom: 10px;
}

.match-preview {
  margin-top: 8px;
  margin-bottom: 5px;
}

.help-button-container {
  text-align: right;
  margin-top: 5px;
  max-width: 1400px;
  margin: 0 auto;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 30px;
  padding-bottom: 20px;
  border-bottom: 1px solid #e4e7ed;
}

.title-with-back {
  display: flex;
  align-items: flex-start;
  gap: 15px;
}

.blue-return-button {
  background: linear-gradient(135deg, #409eff 0%, #66b3ff 100%);
  border: none;
  border-radius: 8px;
  padding: 8px 16px;
  font-weight: 500;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
  transition: all 0.3s ease;
  flex-shrink: 0;
  margin-top: 2px;
}

.blue-return-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(64, 158, 255, 0.4);
  background: linear-gradient(135deg, #66b3ff 0%, #409eff 100%);
}

.title-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.title-main {
  display: flex;
  align-items: center;
  gap: 12px;
}

.title-icon {
  font-size: 28px;
  color: #409eff;
  background: linear-gradient(135deg, #409eff 0%, #66b3ff 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.page-title h2 {
  margin: 0;
  color: #303133;
  font-size: 24px;
  font-weight: 600;
}

.page-description {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 10px 16px;
  background: linear-gradient(135deg, #f5f7fa 0%, #ecf3fc 100%);
  border-left: 3px solid #409eff;
  border-radius: 6px;
  color: #606266;
  font-size: 14px;
  line-height: 1.6;
}

.page-description .el-icon {
  font-size: 16px;
  color: #409eff;
  flex-shrink: 0;
}

.page-description span {
  flex: 1;
}

.main-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-header-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.card-icon {
  font-size: 20px;
  color: #409eff;
  background: linear-gradient(135deg, #409eff 0%, #66b3ff 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.config-form-content {
  margin-top: 20px;
}

.json-template-container {
  width: 100%;
}

.json-template-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
  font-size: 14px;
  color: #606266;
}

.template-actions {
  display: flex;
  gap: 8px;
}

.json-template-editor {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}

.json-validation-status {
  margin-bottom: 10px;
}

.execution-status {
  text-align: center;
  padding: 20px;
}

.execution-progress {
  margin-top: 20px;
}

.execution-message {
  margin-top: 10px;
  color: #606266;
  font-size: 14px;
}

.execution-result {
  margin-top: 20px;
}

.result-data {
  margin-top: 20px;
}

.result-section {
  margin-bottom: 30px;
}

.result-section h4 {
  margin: 0 0 15px 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
  border-left: 4px solid #409EFF;
  padding-left: 10px;
}

.result-section:last-child {
  margin-bottom: 0;
}

/* 结果区域按钮组 */
.result-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 数据区段头部 */
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.section-header h4 {
  margin: 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
  border-left: 4px solid #409EFF;
  padding-left: 10px;
}

.section-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* JSON内容显示 */
.json-content-wrapper {
  background: #f8f9fa;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  overflow: hidden;
}

.json-content {
  margin: 0;
  padding: 16px;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
  font-size: 13px;
  line-height: 1.6;
  color: #2c3e50;
  background: #f8f9fa;
  overflow-x: auto;
  white-space: pre;
  border: none;
  max-height: 400px;
  overflow-y: auto;
}

/* JSON预览 */
.json-preview {
  background: #f0f2f5;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  padding: 10px 12px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.json-preview:hover {
  background: #e6f7ff;
  border-color: #91d5ff;
}

.preview-text {
  color: #666;
  font-size: 13px;
  line-height: 1.4;
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
}
</style>